//
//  DingRtcManager.m
//  ding_rtc
//
//  Created by FXY on 2025/7/30.
//

#import "DingRtcManager.h"

@interface DingRtcManager () <DingRtcEngineDelegate>
@property (nonatomic, strong) DingRtcEngine *rtcEngine;
@property (nonatomic, weak) DingRtcPlugin *plugin;
@property (nonatomic, strong) NSMutableDictionary<NSNumber *, DingRtcView *> *rtcViews;
@end

@implementation DingRtcManager

+ (instancetype)sharedInstance {
    static DingRtcManager *instance;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        instance = [[DingRtcManager alloc] init];
    });
    return instance;
}

- (void)initWithPlugin:(DingRtcPlugin *)plugin
                  extra:(NSString *)extra {
    if (_rtcEngine != nil) return;

    _plugin = plugin;
    _rtcViews = [NSMutableDictionary dictionary];
    _rtcEngine = [DingRtcEngine createInstance:self extras:extra];
    [_rtcEngine publishLocalAudioStream:YES];
    [_rtcEngine publishLocalVideoStream:YES];
    [_rtcEngine subscribeAllRemoteAudioStreams:YES];
    [_rtcEngine subscribeAllRemoteVideoStreams:YES];
    [_rtcEngine setRemoteDefaultVideoStreamType:DingRtcVideoStreamTypeFHD];
}


#pragma mark - 自定义内部方法

- (void)destroy {
    _plugin = nil;
    _rtcViews = nil;
    [DingRtcEngine destroyInstance:_rtcEngine];
    _rtcEngine = nil;

}

- (void)callBackWithMethod:(NSString *)method arguments:(id)arguments{
    if(_plugin) [_plugin callBackToFlutterWithMethod:method arguments:arguments];
}

- (void)onError:(NSInteger)code message:(NSString *)message {
    if(_plugin) [_plugin callBackToFlutterWithMethod:@"onError" arguments:@{
        @"code":@(code),
        @"message": message
    }];
}


- (void)addView:(NSInteger)viewId view:(DingRtcView *)view {
    if (self.rtcViews[@(viewId)] != nil) {
        return;
    }
    self.rtcViews[@(viewId)] = view;
}

- (void)removeView:(NSInteger)viewId {
    [self.rtcViews removeObjectForKey:@(viewId)];
}

- (DingRtcView *)safeViewForId:(NSInteger)viewId {
    DingRtcView *view = self.rtcViews[@(viewId)];
    if (!view) {
        NSLog(@"[DingRtc] safeViewForId failed: no view found for viewId = %ld", (long)viewId);
    }
    return view;
}


#pragma mark - DingRtcEngineDelegate

/// 加入频道回调
- (void)onJoinChannelResult:(int)result channel:(NSString *_Nonnull)channel userId:(NSString *_Nonnull)userId elapsed:(int)elapsed {
    if(result == 0) {
        [_rtcEngine publishLocalAudioStream:YES];
        [_rtcEngine publishLocalVideoStream:YES];
    }
    NSDictionary *params = @{
        @"result":@(result),
        @"channel": [NSString stringWithFormat:@"%@",channel],
        @"userId": [NSString stringWithFormat:@"%@",userId],
        @"elapsed": @(elapsed)
    };
    [self callBackWithMethod:@"onJoinChannelResult" arguments:params];
}

/// 离开频道回调
- (void)onLeaveChannelResult:(int)result stats:(DingRtcStats *_Nonnull)stats {
    [self callBackWithMethod:@"onLeaveChannelResult" arguments:@(result)];
}

/// 远端用户（通信模式）加入频道回调。
- (void)onRemoteUserOnLineNotify:(NSString *)uid elapsed:(int)elapsed {
    [self callBackWithMethod:@"onRemoteUserEnterRoom" arguments:uid];
}

/// 远端用户离开频道回调
- (void)onRemoteUserOffLineNotify:(NSString *_Nonnull)uid offlineReason:(DingRtcUserOfflineReason)reason {
    NSDictionary *params = @{
        @"uid":uid,
        @"reason": [NSString stringWithFormat:@"%ld",reason]
    };
    [self callBackWithMethod:@"onRemoteUserLeaveRoom" arguments:params];
}


/// 远端用户音视频流发生变化
- (void)onRemoteTrackAvailableNotify:(NSString *_Nonnull)uid audioTrack:(DingRtcAudioTrack)audioTrack videoTrack:(DingRtcVideoTrack)videoTrack {
    NSDictionary *params = @{
        @"uid":uid,
        @"audio": @(audioTrack),
        @"video": @(videoTrack)
    };
    [self callBackWithMethod:@"onRemoteStateUpdated" arguments:params];
}

//视频截图回调
//uid 用户uid，为nil或者为""代表本地用户。
- (void)onSnapshotComplete:(NSString*_Nullable)uid videoTrack:(DingRtcVideoTrack)videoTrack filePath:(NSString* _Nullable)filePath width:(int)width height:(int)height success:(BOOL)success{
    NSDictionary *params = @{
        @"uid": uid,
        @"videoTrack": @(videoTrack),
        @"filePath": filePath,
        @"width": width,
        @"height": height,
        @"success": success
    };
    [self callBackWithMethod:@"onSnapshotComplete" arguments:params];
}

#pragma mark - 自定义供flutter调用的方法

/// 进入房间
- (void)enterRoomWithParams:(NSDictionary<NSString *, NSString *> *)params {
    DingRtcAuthInfo *authInfo = [[DingRtcAuthInfo alloc] init];
    authInfo.userId = params[@"meeting_user_id"];
    authInfo.token = params[@"meeting_token"];
    authInfo.appId = params[@"meeting_app_id"];
    authInfo.channelId = params[@"meeting_channel_id"];
    authInfo.gslbServer = params[@"meeting_gslb"];
    
    NSString *userName = params[@"meeting_user_name"];
    [self.rtcEngine joinChannel:authInfo name:userName onResultWithUserId:^(NSInteger errCode, NSString * _Nonnull channel, NSString * _Nonnull userId, NSInteger elapsed) { 
        if(errCode != 0) [self onError:errCode message:@"enter room failure"];
    }];
}

/// 离开房间
- (void)leaveRoom {
    [self.rtcEngine stopPreview];
    [self.rtcEngine publishLocalAudioStream:NO];
    [self.rtcEngine publishLocalVideoStream:NO];
    [self.rtcEngine leaveChannel];
}

/// 设置日志等级
- (void)setLogLevel:(NSInteger)value {
    for (NSInteger level = 0; level <= DingRtcLogLevelNone; level++) {
        if (level == value) {
            [DingRtcEngine setLogLevel:(DingRtcLogLevel)level];
            break;
        }
    }
}


/// 开始预览本地
- (void)startLocalPreviewWithCamera:(BOOL)isFrontCamera viewId:(NSInteger)viewId {
    DingRtcView *view = [self safeViewForId:viewId];
    if (!view) {
        NSLog(@"startLocalPreview: view is null. viewId=%ld", (long)viewId);
        return;
    }
    DingRtcCameraCapturerConfiguration *configuration = [[DingRtcCameraCapturerConfiguration alloc] init];
    configuration.cameraDirection = isFrontCamera ? DingRtcCameraDirectionFront : DingRtcCameraDirectionBack;
    [self.rtcEngine setCameraCapturerConfiguration:configuration];
    [self.rtcEngine setLocalViewConfig:view.canvas forTrack:DingRtcVideoTrackCamera];
    [self.rtcEngine startPreview];
}

/// 开始预览远端
- (void)startRemoteViewWithUserId:(NSString *)userId viewId:(NSInteger)viewId {
    DingRtcView *view = [self safeViewForId:viewId];
    if (!view) {
        NSLog(@"[DingRtc] startRemoteView: view is nil. viewId = %ld", (long)viewId);
        return;
    }
    [self.rtcEngine setRemoteViewConfig:view.canvas uid:userId forTrack:DingRtcVideoTrackCamera];
}


- (void)enableSpeakerphone:(BOOL)enable {
    [self.rtcEngine enableSpeakerphone:enable];
}

- (void)muteLocalAudio:(BOOL)mute {
    [self.rtcEngine muteLocalMic:mute mode:DingRtcMuteAudioModeDefault];
}

- (void)enableLocalVideo:(BOOL)enable {
    [self.rtcEngine enableLocalVideo:enable];
}

- (void)stopLocalPreview {
    [self.rtcEngine stopPreview];
}

- (void)switchCamera {
    [self.rtcEngine switchCamera];
}

// 更新远端用户视频的视图
- (void)updateRemoteVideoRender:(DingRtcVideoCanvas *)canvas
                            uid:(NSString *)uid
                       isScreen:(BOOL)isScreen {
    if (isScreen) {
        
        [self.rtcEngine setRemoteViewConfig:nil
                                     uid:uid
                                   forTrack:DingRtcVideoTrackScreen];
        [self.rtcEngine setRemoteViewConfig:canvas
                                     uid:uid
                                   forTrack:DingRtcVideoTrackScreen];
    } else {
        [self.rtcEngine setRemoteViewConfig:nil
                                     uid:uid
                                   forTrack:DingRtcVideoTrackCamera];
        [self.rtcEngine setRemoteViewConfig:canvas
                                     uid:uid
                                   forTrack:DingRtcVideoTrackCamera];
    }
}

// 更新本地用户视频的视图
- (void)updateLocalVideoRender:(DingRtcVideoCanvas *)canvas
                      isScreen:(BOOL)isScreen {
    if (isScreen) {
        [self.rtcEngine setLocalViewConfig:nil
                                  forTrack:DingRtcVideoTrackScreen];
        [self.rtcEngine setLocalViewConfig:canvas
                                  forTrack:DingRtcVideoTrackScreen];
    } else {
        [self.rtcEngine setLocalViewConfig:nil
                                  forTrack:DingRtcVideoTrackCamera];
        [self.rtcEngine setLocalViewConfig:canvas
                                  forTrack:DingRtcVideoTrackCamera];
    }
}

/// 用户视频进行截图
- (NSInteger) snapshotVideo:(NSString *)userId filePath:(NSString *)filePath isScreen:(BOOL)isScreen{
    if (isScreen) {
        return [self.rtcEngine snapshotVideo:userId type:DingRtcVideoTrackScreen filePath:filePath];
    } else {
        return [self.rtcEngine snapshotVideo:userId type:DingRtcVideoTrackCamera filePath:filePath];
    }
}


@end
